Video abstract for "An Adaptive Homeostatic Algorithm for the Unsupervised Learning of Visual Features"
This video shows the results of unsupervised learning with different type of kezrnel normalization. This is to illustrate the results obtained in this paper on the An Adaptive Homeostatic Algorithm for the Unsupervised Learning of Visual Features which is now in press.
In [1]:
%matplotlib inline
In [8]:
%ls -ltr /tmp/cache_dir
In [9]:
%ls -ltr /tmp/2019-09-11*
In [4]:
%rm /tmp/cache_dir/*lock*
#%rm/tmp/2019-09-11*
In [94]:
d_new, d_old = 1, 1
N_step = 16
for i_step in range(N_step):
print(d_new, d_old)
d_new, d_old = d_new + d_old, d_new
In [16]:
%%writefile /tmp/video_abstract.py
#initialize
import os
import numpy as np
np.set_printoptions(precision=2, suppress=True)
seed = 42
np.random.seed(seed)
from shl_scripts.shl_experiments import SHL
#from shl_scripts import sparse_encode
name = '2019-09-11_Perrinet19'
datapath = '/tmp/database'
opts = dict(datapath=datapath, verbose=0, cache_dir='/tmp/cache_dir', n_iter=2**5 + 1, seed=seed)
shl = SHL(**opts)
data = shl.get_data(matname=f'{name}_data')
# running main simulations
# Figure 1 & 3
N_cv = 1
homeo_methods = ['None', 'OLS', 'HEH', 'HAP']
n_jobs = 1
N_step = 12
N_step = 16
from shl_scripts import touch
#from shl_scripts.shl_experiments import SHL_set
for homeo_method, color in zip(homeo_methods, colors):
print(f'=> homeo_method={homeo_method}')
flockname = os.path.join(shl.cache_dir, f'{name}_{homeo_method}_lock')
if not os.path.isfile(flockname):
touch(fmatname + '_lock')
# TODO use fibonacci
d_new, d_old = 1, 1
for i_step in range(N_step):
opts_ = opts.copy()
n_iter = int(base_iter**i_step + 1)
print(f'==> i_iter={i_step} / n_iter={d_new}')
opts_.update(homeo_method=homeo_method, n_iter=d_old,)
shl = SHL(**opts)
if i_step==0:
dictionary = None
else:
dictionary = shl.learn_dico(data=data, matname=f'{name}_{homeo_method}_{i_step-1}', list_figures=[]).dictionary
dico = shl.learn_dico(data=data, dictionary=dictionary, matname=f'{name}_{homeo_method}_{i_step}', list_figures=[])
d_new, d_old = d_new + d_old, d_new
if os.path.isfile(flockname): os.remove(flockname)
In [15]:
%run /tmp/video_abstract.py
In [69]:
homeo_methods
Out[69]:
In [72]:
phi = (np.sqrt(5) + 1. ) /2
fig_width = 15
dpi_export = 300
#dpi_export = 0
colors = ['black', 'orange', 'blue', 'red']
In [ ]:
import matplotlib.pyplot as plt
def plot_dico(dico, color, dim_graph = (8, 8)):
subplotpars = dict(left=0.05, right=.95, bottom=0.05, top=.95, wspace=0.05, hspace=0.05,)
fig, axs = plt.subplots(1, 2, figsize=(fig_width, fig_width/(1+phi)), gridspec_kw=subplotpars)
for ax in axs:
ax.axis(c='b', lw=2, axisbg='w')
ax.set_facecolor('w')
from shl_scripts import show_dico
fig, axs[0] = show_dico(shl, dico, data=data, dim_graph=dim_graph, fig=fig, ax=axs[0], order=False)
if False:
from shl_scripts import plot_P_cum
fig, axs[1] = plot_P_cum(dico.P_cum, ymin=0.6, ymax=1.001,
title=None, suptitle=None, ylabel='non-linear functions',
verbose=False, n_yticks=21, alpha=.02, c=color, fig=fig, ax=axs[1])
axs[1].plot([0], [0], lw=1, color=color, label=homeo_method, alpha=.6)
else:
from shl_scripts import plot_proba_histogram
coding = shl.code(data, dico)
fig, axs[1] = plot_proba_histogram(coding, fig=fig, ax=axs[1])
axs[1].plot([0], [0], lw=1, color=color, label=homeo_method, alpha=.6)
# ax.set_ylabel(homeo_method)
#ax.text(-8, 7*dim_graph[0], homeo_method, fontsize=12, color='k', rotation=90)#, backgroundcolor='white'
#axs[1].legend(loc='lower right')
return fig, axs
for homeo_method, color in zip(homeo_methods, colors):
print(f'=> homeo_method={homeo_method}')
for i_step in range(N_step):
print(f'==> i_iter={i_step} / n_iter={n_iter}')
figname = f'/tmp/{name}_{homeo_method}_{i_step}.png'
if not os.path.isfile(figname):
fig, axs = plot_dico(dico, color)
axs[1].set_ylim(0. 1.7)
axs[1].text(10, 0.1, f'homeo_method={homeo_method}', fontsize=24, color=color, rotation=0)#, backgroundcolor='white'
axs[1].text(10, 1.5, f'n_iter={n_iter}', fontsize=24, color='k', rotation=0)#, backgroundcolor='white'
plt.show()
if dpi_export > 0 : fig.savefig(figname, dpi=dpi_export, bbox_inches='tight')
Creating the movie using the (excellent) MoviePy library:
In [39]:
[f'/tmp/{name}_{homeo_method}_{i_step}.png' for i_step in range(N_step)]
Out[39]:
In [42]:
vext = 'mp4'
from moviepy.editor import ImageSequenceClip
for homeo_method in homeo_methods:
clip = ImageSequenceClip([f'/tmp/{name}_{homeo_method}_{i_step}.png' for i_step in range(N_step)], fps=2)
clip.write_videofile(f'/tmp/{name}_{homeo_method}.{vext}')
Annotating the movie using the (excellent) MoviePy library:
In [81]:
from moviepy.editor import VideoFileClip, ImageClip, TextClip, CompositeVideoClip
H = 500
W = 800
SIZE = (W, H)
#clip = [VideoFileClip(f'/tmp/{name}_{homeo_method}.{vext}')]
clip = []
t = 0
texts = ["An Adaptive Homeostatic Algorithm\n for the Unsupervised Learning\n of Visual Features",
"as published Sep 2019\n in the journal Vision"
]
colors_intro = ['orange', 'white']
txt_opts = dict(fontsize=50, font="Amiri-Bold", stroke_color='gray', stroke_width=.5, size=(W,H))
duration = 3
for text, color in zip(texts, colors_intro):
txt_clip = TextClip(text, color=color, **txt_opts)
txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)#.resize(height=H, width=W)
t += duration
clip.append(txt_clip)
In [74]:
colors
Out[74]:
In [82]:
texts = ["No homeostasis", "Olshausen (1997)", "Histogram Equalization", "Activation Probability"]
subtitles = {}
subtitles['None'] = [
'I show here the result of learning...',
'... evolving with the number of iterations ...',
'... on the left the receptive fields (kernels) ...',
'... by showing 64 randomly picked from the 661 cells ...',
'... and on the right histogram of activation probability.',
'... After some iterations, edge-like filters appear ...',
'... but the histogram shows a desequilibrium in the ...',
'... activation probability, even though ...',
'... the norm of the kerenals are normalized.',
]
subtitles['OLS'] = [
'The original homeostasis algorithm developped ...',
'... by Olshausen and Field (1997) included a more ...',
'... elaborated adaptation based on the variance of ...',
'... the coefficients, yielding a better balance...',
'... ...',
'Still, this causes an under-optimisation of the ... ',
'... sparse code as some are a priori ...',
'... more likely to be selected than ...',
'... others ...',
]
subtitles['HEH'] = [
'Such an objective can be simply optimzed...',
'... by introducing an adaptive non-linearity in our ...',
'... sparse coding algorithm. This non-linearity ...',
'... is based on the concept of histogram normalization ...',
'... to make sure that all neurons are always picked up.',
'... with a priori the same probability ...',
'... We called this Histogram Equalization Homeostasis ...',
'... and it effectively works very well, as well ...',
'... qualitatively (left) than quantitatively (right).',
]
subtitles['HAP'] = [
'A problem of Histogram Equalization Homeostasis ...',
'... is that it is computationally more expensive ...',
'... and less plausible to be implemented in real ...',
'... biological neurons. We thus explored another...',
'... algorithm simply based on the activation probability.',
'This Homeostasis on the Activation Probability ... ',
'... performed qualitatively as well as HEH ...',
'... and also quantitatively similarly ...',
'Yet it comes at a very low cost compatible with biomimetic algorithms',
]
txt_opts = dict(fontsize=20, font="Amiri-Bold", stroke_color='gray', stroke_width=.5, size=(W,H))
for homeo_method, text, color in zip(homeo_methods, texts, colors):
print(f'=> homeo_method={homeo_method}')
duration = 1
txt_clip = TextClip(text, color=color, **txt_opts)
txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)
t += duration
clip.append(txt_clip)
#clip = [VideoFileClip(f'{name}_{homeo_method}.{vext}')]
for i_step in range(N_step):
duration = 1
im_clip = ImageClip(f'/tmp/{name}_{homeo_method}_{i_step}.png')
im_clip = im_clip.set_start(t).set_duration(duration)
t += duration
clip.append(im_clip)
In [83]:
print(homeo_methods, texts, colors)
for homeo_method, text, color in zip(homeo_methods, texts, colors):
print(homeo_method, text, color)
In [84]:
texts = ["... find more info, and open-sourced code @ ",
"https://laurentperrinet.github.io/publication/perrinet-19"]
txt_opts = dict(fontsize=50, font="Amiri-Bold", stroke_color='gray', stroke_width=.5, size=(W,H))
duration = 3
for text, color in zip(texts, colors):
txt_clip = TextClip(text, color=color, **txt_opts)
txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)
t += duration
clip.append(txt_clip)
In [85]:
clip
Out[85]:
In [86]:
# Overlay the text clip on the first video clip
video = CompositeVideoClip(clip)
# Write the result to a file (many options available !)
video.write_videofile(f'../files/{name}.{vext}', fps=5)
In [37]:
%pwd
Out[37]:
some book keeping for the notebook¶
In [ ]:
%load_ext version_information
%version_information numpy, scipy, matplotlib, MotionClouds
Comments
Comments powered by Disqus